<script lang="tsx">
/**
 * 表单组件
 */
export default {
  name: "sheet-form"
}
</script>

<script lang="tsx" setup>
import SheetFormManager from "./sheet-form-manager.ts"
import {ref, defineProps, watch, reactive, computed} from "vue"
import {cloneDeep} from "lodash"
import {Render} from "../../../core"
import {ElMessage, ElTabs, ElTabPane, ElRow, ElCol} from "element-plus";

/**
 * 定义props
 */
const propsData = defineProps<{
  SheetFormModel: SheetFormManager<any>
  reflections?: any;
}>()

/**
 * 表单校验
 */
const ruleFormRef = ref()
const rules: any = reactive<any>({})

/**
 * 表单模型
 */
const sheetFormModel: any = ref<SheetFormManager<any>>()

/**
 * 表单数据
 */
const sheetFormData = ref<any>({})

/**
 * 当前激活的tab
 */
const activeTab = ref<string>()

/**
 * 按tab分组的表单元素
 */
const groupedByTab = computed(() => {
  if (!sheetFormModel.value?.els) return {}
  
  const groups: Record<string, any[]> = {}
  sheetFormModel.value.els.forEach((item: any) => {
    const tabName = item.tabName || 'default'
    if (!groups[tabName]) {
      groups[tabName] = []
    }
    groups[tabName].push(item)
  })
  
  // 如果只有默认tab且没有指定tabName的元素，则不使用tabs
  const tabNames = Object.keys(groups)
  if (tabNames.length === 1 && tabNames[0] === 'default') {
    return {}
  }
  
  return groups
})

/**
 * 按section分组的表单元素
 */
const groupedBySection = (items: any[]) => {
  const groups: Record<string, any[]> = {}
  items.forEach((item: any) => {
    const sectionName = item.sectionName || 'default'
    if (!groups[sectionName]) {
      groups[sectionName] = []
    }
    groups[sectionName].push(item)
  })
  return groups
}

/**
 * 设置校验规则
 */
const refreshRule = () => {
  rules.value = {}
  const ruleList = sheetFormModel.value.els.filter((item: any) => !!sheetFormModel.value.required.find((itemData: any) => itemData === item.prop))
  ruleList.forEach((item: any) => {
    rules[item.prop] = [{
      required: true,
      message: `${item.label}是必填项，请填写`,
      trigger: 'change'
    }]
  })
}

/**
 * 监听
 */
watch(() => propsData.SheetFormModel, function (newValue: any) {
  if (newValue) {
    console.log(newValue)
    sheetFormModel.value = newValue
    if (newValue.required) {
      refreshRule()
    }
    
    // 设置默认激活的tab
    const tabs = Object.keys(groupedByTab.value)
    if (tabs.length > 0) {
      activeTab.value = tabs[0]
    }
  }
}, {
  deep: true,
  immediate: true
})

/**
 * 初始化表单数据
 */
const initFormData = () => {
  if (sheetFormModel.value?.initValue) {
    setFormData(sheetFormModel.value?.initValue)
  } else {
    setFormData({})
  }
}

/**
 * 设置组件值
 */
const handleSetData = (item?: any) => {
  if (item) {
    sheetFormData.value[item.key] = item.value
  }
}

/**
 * 获取表单原始数据
 */
const getFormData = async () => {
  const result = await ruleFormRef.value.validate((valid: boolean, fields: any) => {
    if (!valid) {
      const list: any = Object.values(fields)?.flat()
      if (list.length > 0) {
        const message = list[0]?.message
        ElMessage.error(message)
      }
    }
  })
  if (!result) return false
  if (sheetFormModel.value?.beforeSubmit) {
    return await sheetFormModel.value.beforeSubmit(sheetFormData.value)
  }
  return sheetFormData.value
}

/**
 * 直接获取表单数据
 */
const getFormDataDirect = async () => {
  return sheetFormData.value
}

/**
 * 设置表单数据
 */
const setFormData = async (data: any) => {
  if (typeof (sheetFormModel.value?.bindData) === "function") {
    let result = sheetFormModel.value.bindData(data)
    if (result instanceof Promise) {
      result = await result
    }
    sheetFormData.value = cloneDeep(result)
  } else {
    sheetFormData.value = cloneDeep(data)
  }
}

/**
 * 直接设置表单数据
 */
const setFormDataDirect = (data: any) => {
  sheetFormData.value = cloneDeep(data)
}

/**
 * 是否显示
 */
const isShow = (item: any) => {
  const func = item.show as Function
  if (!func) {
    return true
  }
  return func(sheetFormData.value)
}

/**
 * 暴露
 */
defineExpose({
  initFormData,
  getFormData,
  getFormDataDirect,
  setFormData,
  setFormDataDirect,
  refreshRule
})
</script>

<template>
  <div class="sheet-form">
    <div class="form-content">
      <el-scrollbar>
        <el-form ref="ruleFormRef" v-model="sheetFormData" :model="sheetFormData" :rules="rules">
          <!-- 使用tabs分组 -->
          <el-tabs v-if="Object.keys(groupedByTab).length > 0" v-model="activeTab">
            <el-tab-pane 
              v-for="(tabItems, tabName) in groupedByTab" 
              :key="tabName" 
              :label="tabName === 'default' ? '基本信息' : tabName" 
              :name="tabName"
            >
              <div v-for="(sectionItems, sectionName) in groupedBySection(tabItems)" :key="sectionName">
                <el-row v-if="sectionName !== 'default'" class="section-title">
                  <el-col :span="24">
                    <div class="section-title-content">{{ sectionName }}</div>
                  </el-col>
                </el-row>
                <el-row :gutter="10">
                  <el-col
                    v-for="(item, index) in sectionItems"
                    :key="index"
                    :span="item.span || 24"
                    v-show="isShow(item)"
                  >
                    <el-form-item 
                      :label="item.label" 
                      :label-width="sheetFormModel.labelWidth" 
                      :prop="item.prop"
                    >
                      <Render 
                        :data="sheetFormData" 
                        :item="item" 
                        :reflections="propsData.reflections" 
                        :renderType="'form'"
                        @setData="handleSetData"
                      />
                    </el-form-item>
                  </el-col>
                </el-row>
              </div>
            </el-tab-pane>
          </el-tabs>
          
          <!-- 不使用tabs -->
          <template v-else>
            <div v-for="(sectionItems, sectionName) in groupedBySection(sheetFormModel.els)" :key="sectionName">
              <el-row v-if="sectionName !== 'default'" class="section-title">
                <el-col :span="24">
                  <div class="section-title-content">{{ sectionName }}</div>
                </el-col>
              </el-row>
              <el-row :gutter="20">
                <el-col
                  v-for="(item, index) in sectionItems"
                  :key="index"
                  :span="item.span || 24"
                  v-show="isShow(item)"
                >
                  <el-form-item 
                    :label="item.label" 
                    :label-width="sheetFormModel.labelWidth" 
                    :prop="item.prop"
                  >
                    <Render 
                      :data="sheetFormData" 
                      :item="item" 
                      :reflections="propsData.reflections" 
                      :renderType="'form'"
                      @setData="handleSetData"
                    />
                  </el-form-item>
                </el-col>
              </el-row>
            </div>
          </template>
        </el-form>
      </el-scrollbar>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.sheet-form {
  .section-title {
    margin: 5px 0;

    .section-title-content {
      border-left: 4px solid #409eff;
      padding-left: 10px;
      font-weight: bold;
      color: #333;
      font-size: 16px;
    }
  }
  
  :deep(.el-form-item) {
    width: 100%;
  }
}
</style>